home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / EXAMPLES / TEXENV.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  19.1 KB  |  754 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1994. */
  3.  
  4. /**
  5.  * (c) Copyright 1993, Silicon Graphics, Inc.
  6.  * ALL RIGHTS RESERVED 
  7.  * Permission to use, copy, modify, and distribute this software for 
  8.  * any purpose and without fee is hereby granted, provided that the above
  9.  * copyright notice appear in all copies and that both the copyright notice
  10.  * and this permission notice appear in supporting documentation, and that 
  11.  * the name of Silicon Graphics, Inc. not be used in advertising
  12.  * or publicity pertaining to distribution of the software without specific,
  13.  * written prior permission. 
  14.  *
  15.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  16.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  17.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  18.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  19.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  20.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  21.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  22.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  23.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  24.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  25.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  26.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  * 
  28.  * US Government Users Restricted Rights 
  29.  * Use, duplication, or disclosure by the Government is subject to
  30.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  31.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  32.  * clause at DFARS 252.227-7013 and/or in similar or successor
  33.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  34.  * Unpublished-- rights reserved under the copyright laws of the
  35.  * United States.  Contractor/manufacturer is Silicon Graphics,
  36.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  37.  *
  38.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  39.  */
  40.  
  41. /* Demonstrates texture environment modes and internal image formats.
  42.    Requires the GL_EXT_texture extension.  */
  43.  
  44. #include <stdio.h>
  45. #include <stdlib.h>
  46. #include <string.h>
  47. #include <GL/glut.h>
  48.  
  49. #undef max
  50. #undef min
  51. #define max(a,b)    ((a) >= (b) ? (a) : (b))
  52. #define min(a,b)    ((a) <= (b) ? (a) : (b))
  53. /* *INDENT-OFF* */
  54. GLfloat lightCheck[4] = {0.7, 0.7, 0.7, 1.0};
  55. GLfloat darkCheck[4] = {0.3, 0.3, 0.3, 1.0};
  56.  
  57. GLfloat labelColor0[4] = {1.0, 1.0, 1.0, 1.0};
  58. GLfloat labelColor1[4] = {1.0, 1.0, 0.4, 1.0};
  59. GLfloat *labelInfoColor = labelColor0;
  60. GLfloat labelLevelColor0[4] = {0.8, 0.8, 0.1, 1.0};
  61. GLfloat labelLevelColor1[4] = {0.0, 0.0, 0.0, 1.0};
  62. /* *INDENT-ON* */
  63.  
  64. GLboolean doubleBuffered = GL_FALSE;
  65. GLboolean drawBackground = GL_FALSE;
  66. GLboolean drawBlended = GL_TRUE;
  67. GLboolean drawSmooth = GL_FALSE;
  68. GLboolean drawTextured = GL_TRUE;
  69. GLboolean displayLevelInfo = GL_FALSE;
  70.  
  71. int textureWidth = 64;
  72. int textureHeight = 64;
  73.  
  74. int winWidth = 580, winHeight = 720;
  75.  
  76. struct formatInfo {
  77.   GLenum baseFormat;
  78.   GLenum internalFormat;
  79.   char *name;
  80. };
  81.  
  82. #define NUM_LUMINANCE_FORMATS \
  83.         (sizeof(luminanceFormats) / sizeof(luminanceFormats[0]))
  84. struct formatInfo luminanceFormats[] =
  85. {
  86.   {GL_LUMINANCE, 1, "LUMINANCE"},
  87. #if GL_EXT_texture
  88.   {GL_LUMINANCE, GL_LUMINANCE4_EXT, "LUMINANCE4"},
  89.   {GL_LUMINANCE, GL_LUMINANCE8_EXT, "LUMINANCE8"},
  90.   {GL_LUMINANCE, GL_LUMINANCE12_EXT, "LUMINANCE12"},
  91.   {GL_LUMINANCE, GL_LUMINANCE16_EXT, "LUMINANCE16"},
  92. #endif
  93. };
  94.  
  95. #define NUM_ALPHA_FORMATS \
  96.         (sizeof(alphaFormats) / sizeof(alphaFormats[0]))
  97. struct formatInfo alphaFormats[] =
  98. {
  99.   {GL_ALPHA, GL_ALPHA, "ALPHA"},
  100. #if GL_EXT_texture
  101.   {GL_ALPHA, GL_ALPHA4_EXT, "ALPHA4"},
  102.   {GL_ALPHA, GL_ALPHA8_EXT, "ALPHA8"},
  103.   {GL_ALPHA, GL_ALPHA12_EXT, "ALPHA12"},
  104.   {GL_ALPHA, GL_ALPHA16_EXT, "ALPHA16"},
  105. #endif
  106. };
  107.  
  108. #if GL_EXT_texture
  109. #define NUM_INTENSITY_FORMATS \
  110.         (sizeof(intensityFormats) / sizeof(intensityFormats[0]))
  111. struct formatInfo intensityFormats[] =
  112. {
  113.   {GL_INTENSITY_EXT, GL_INTENSITY_EXT, "INTENSITY"},
  114.   {GL_INTENSITY_EXT, GL_INTENSITY4_EXT, "INTENSITY4"},
  115.   {GL_INTENSITY_EXT, GL_INTENSITY8_EXT, "INTENSITY8"},
  116.   {GL_INTENSITY_EXT, GL_INTENSITY12_EXT, "INTENSITY12"},
  117.   {GL_INTENSITY_EXT, GL_INTENSITY16_EXT, "INTENSITY16"},
  118. };
  119. #endif
  120.  
  121. #define NUM_LUMINANCE_ALPHA_FORMATS \
  122.         (sizeof(luminanceAlphaFormats) / sizeof(luminanceAlphaFormats[0]))
  123. struct formatInfo luminanceAlphaFormats[] =
  124. {
  125.   {GL_LUMINANCE_ALPHA, 2, "LUMINANCE_ALPHA"},
  126. #if GL_EXT_texture
  127.   {GL_LUMINANCE_ALPHA, GL_LUMINANCE4_ALPHA4_EXT, "LUMINANCE4_ALPHA4"},
  128.   {GL_LUMINANCE_ALPHA, GL_LUMINANCE6_ALPHA2_EXT, "LUMINANCE6_ALPHA2"},
  129.   {GL_LUMINANCE_ALPHA, GL_LUMINANCE8_ALPHA8_EXT, "LUMINANCE8_ALPHA8"},
  130.   {GL_LUMINANCE_ALPHA, GL_LUMINANCE12_ALPHA4_EXT, "LUMINANCE12_ALPHA4"},
  131.   {GL_LUMINANCE_ALPHA, GL_LUMINANCE12_ALPHA12_EXT, "LUMINANCE12_ALPHA12"},
  132.   {GL_LUMINANCE_ALPHA, GL_LUMINANCE16_ALPHA16_EXT, "LUMINANCE16_ALPHA16"},
  133. #endif
  134. };
  135.  
  136. #define NUM_RGB_FORMATS \
  137.         (sizeof(rgbFormats) / sizeof(rgbFormats[0]))
  138. struct formatInfo rgbFormats[] =
  139. {
  140.   {GL_RGB, 3, "RGB"},
  141. #if GL_EXT_texture
  142.   {GL_RGB, GL_RGB2_EXT, "RGB2"},
  143.   {GL_RGB, GL_RGB4_EXT, "RGB4"},
  144.   {GL_RGB, GL_RGB5_EXT, "RGB5"},
  145.   {GL_RGB, GL_RGB8_EXT, "RGB8"},
  146.   {GL_RGB, GL_RGB10_EXT, "RGB10"},
  147.   {GL_RGB, GL_RGB12_EXT, "RGB12"},
  148.   {GL_RGB, GL_RGB16_EXT, "RGB16"},
  149. #endif
  150. };
  151.  
  152. #define NUM_RGBA_FORMATS \
  153.         (sizeof(rgbaFormats) / sizeof(rgbaFormats[0]))
  154. struct formatInfo rgbaFormats[] =
  155. {
  156.   {GL_RGBA, 4, "RGBA"},
  157. #if GL_EXT_texture
  158.   {GL_RGBA, GL_RGBA2_EXT, "RGBA2"},
  159.   {GL_RGBA, GL_RGBA4_EXT, "RGBA4"},
  160.   {GL_RGBA, GL_RGBA8_EXT, "RGBA8"},
  161.   {GL_RGBA, GL_RGBA12_EXT, "RGBA12"},
  162.   {GL_RGBA, GL_RGBA16_EXT, "RGBA16"},
  163.   {GL_RGBA, GL_RGB5_A1_EXT, "RGB5_A1"},
  164.   {GL_RGBA, GL_RGB10_A2_EXT, "RGB10_A2"},
  165. #endif
  166. };
  167.  
  168. struct baseFormatInfo {
  169.   struct formatInfo *format;
  170.   int current, number;
  171. };
  172.  
  173. #define NUM_BASE_FORMATS \
  174.         (sizeof(baseFormats) / sizeof(baseFormats[0]))
  175. int baseFormat;
  176. struct baseFormatInfo baseFormats[] =
  177. {
  178.   {luminanceFormats, 0, NUM_LUMINANCE_FORMATS},
  179.   {alphaFormats, 0, NUM_ALPHA_FORMATS},
  180. #if GL_EXT_texture
  181.   {intensityFormats, 0, NUM_INTENSITY_FORMATS},
  182. #endif
  183.   {luminanceAlphaFormats, 0, NUM_LUMINANCE_ALPHA_FORMATS},
  184.   {rgbFormats, 0, NUM_RGB_FORMATS},
  185.   {rgbaFormats, 0, NUM_RGBA_FORMATS},
  186. };
  187.  
  188. #define NUM_ENV_COLORS \
  189.         (sizeof(envColors) / sizeof(envColors[0]))
  190. int envColor;
  191. GLfloat envColors[][4] =
  192. {
  193.   {0.0, 0.0, 0.0, 1.0},
  194.   {1.0, 0.0, 0.0, 1.0},
  195.   {0.0, 1.0, 0.0, 1.0},
  196.   {0.0, 0.0, 1.0, 1.0},
  197.   {1.0, 1.0, 1.0, 1.0},
  198. };
  199.  
  200. struct envModeInfo {
  201.   GLenum mode;
  202.   char *name;
  203. };
  204.  
  205. #define NUM_ENV_MODES \
  206.         (sizeof(envModes) / sizeof(envModes[0]))
  207. struct envModeInfo envModes[] =
  208. {
  209. #if GL_EXT_texture
  210.   {GL_REPLACE_EXT, "REPLACE"},
  211. #endif
  212.   {GL_MODULATE, "MODULATE"},
  213.   {GL_BLEND, "BLEND"},
  214.   {GL_DECAL, "DECAL"},
  215. };
  216.  
  217. void
  218. checkErrors(void)
  219. {
  220.   GLenum error;
  221.   while ((error = glGetError()) != GL_NO_ERROR) {
  222.     fprintf(stderr, "Error: %s\n", (char *) gluErrorString(error));
  223.   }
  224. }
  225.  
  226. static void
  227. drawString(char *string, GLfloat x, GLfloat y, GLfloat color[4])
  228. {
  229.   glColor4fv(color);
  230.   glRasterPos2f(x, y);
  231.   while (*string) {
  232.     glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, *string);
  233.     string++;
  234.   }
  235. }
  236.  
  237. static void
  238. drawStringOutline(char *string, GLfloat x, GLfloat y,
  239.   GLfloat color[4], GLfloat outline[4])
  240. {
  241.   drawString(string, x - 1, y, outline);
  242.   drawString(string, x + 1, y, outline);
  243.   drawString(string, x, y - 1, outline);
  244.   drawString(string, x, y + 1, outline);
  245.   drawString(string, x, y, color);
  246. }
  247.  
  248. static void
  249. begin2D(int width, int height)
  250. {
  251.   glMatrixMode(GL_PROJECTION);
  252.   glPushMatrix();
  253.   glLoadIdentity();
  254.   glOrtho(0, width, 0, height, -1, 1);
  255.   glMatrixMode(GL_MODELVIEW);
  256.   glPushMatrix();
  257.   glLoadIdentity();
  258. }
  259.  
  260. static void
  261. end2D(void)
  262. {
  263.   glMatrixMode(GL_PROJECTION);
  264.   glPopMatrix();
  265.   glMatrixMode(GL_MODELVIEW);
  266.   glPopMatrix();
  267. }
  268.  
  269. static void
  270. initialize(void)
  271. {
  272.   glMatrixMode(GL_PROJECTION);
  273.   glLoadIdentity();
  274.   glOrtho(-1.5, 1.5, -1.5, 1.5, -1.5, 1.5);
  275.   glMatrixMode(GL_MODELVIEW);
  276.   glLoadIdentity();
  277.  
  278.   glShadeModel(GL_FLAT);
  279. }
  280.  
  281. /* ARGSUSED1 */
  282. void
  283. keyboard(unsigned char c, int x, int y)
  284. {
  285.   switch (c) {
  286.   case 'c':
  287.     envColor = ++envColor % (int) NUM_ENV_COLORS;
  288.     break;
  289.   case 'g':
  290.     drawBackground = !drawBackground;
  291.     break;
  292.   case 'b':
  293.     drawBlended = !drawBlended;
  294.     break;
  295.   case 's':
  296.     drawSmooth = !drawSmooth;
  297.     break;
  298.   case 't':
  299.     drawTextured = !drawTextured;
  300.     break;
  301.   case 'i':
  302.     displayLevelInfo = !displayLevelInfo;
  303.     break;
  304.   case 27:             /* Escape key should force exit. */
  305.     exit(0);
  306.     break;
  307.   default:
  308.     break;
  309.   }
  310.   glutPostRedisplay();
  311. }
  312.  
  313. /* ARGSUSED1 */
  314. void
  315. special(int key, int x, int y)
  316. {
  317.   switch (key) {
  318.   case GLUT_KEY_DOWN:
  319.     if (++baseFormat > NUM_BASE_FORMATS - 1)
  320.       baseFormat = 0;
  321.     break;
  322.   case GLUT_KEY_UP:
  323.     if (--baseFormat < 0)
  324.       baseFormat = NUM_BASE_FORMATS - 1;
  325.     break;
  326.   case GLUT_KEY_LEFT:
  327.     --baseFormats[baseFormat].current;
  328.     if (baseFormats[baseFormat].current < 0)
  329.       baseFormats[baseFormat].current =
  330.         baseFormats[baseFormat].number - 1;
  331.     break;
  332.   case GLUT_KEY_RIGHT:
  333.     ++baseFormats[baseFormat].current;
  334.     if (baseFormats[baseFormat].current > baseFormats[baseFormat].number - 1)
  335.       baseFormats[baseFormat].current = 0;
  336.     break;
  337.   default:
  338.     break;
  339.   }
  340.   glutPostRedisplay();
  341. }
  342.  
  343. void
  344. reshape(int w, int h)
  345. {
  346.   winWidth = w;
  347.   winHeight = h;
  348.   /* No need to call glViewPort here since "draw" calls it! */
  349. }
  350.  
  351. static void
  352. loadTexture(int width, int height, struct formatInfo *format)
  353. {
  354.   int luminanceSize = 0;
  355.   int alphaSize = 0;
  356.   int rgbSize = 0;
  357.   GLenum textureFormat;
  358.   GLubyte *texImage, *p;
  359.   int elementsPerGroup, elementSize, groupSize, rowSize;
  360.   int i, j;
  361.  
  362.   switch (format->baseFormat) {
  363.   case GL_LUMINANCE:
  364. #if GL_EXT_texture
  365.   case GL_INTENSITY_EXT:
  366. #endif
  367.     luminanceSize = 1;
  368.     textureFormat = GL_LUMINANCE;
  369.     break;
  370.   case GL_ALPHA:
  371.     alphaSize = 1;
  372.     textureFormat = GL_ALPHA;
  373.     break;
  374.   case GL_LUMINANCE_ALPHA:
  375.     luminanceSize = 1;
  376.     alphaSize = 1;
  377.     textureFormat = GL_LUMINANCE_ALPHA;
  378.     break;
  379.   case GL_RGB:
  380.     rgbSize = 3;
  381.     textureFormat = GL_RGB;
  382.     break;
  383.   case GL_RGBA:
  384.     rgbSize = 3;
  385.     alphaSize = 1;
  386.     textureFormat = GL_RGBA;
  387.     break;
  388.   default:
  389.     fprintf(stderr, "bad internal format info\n");
  390.     return;
  391.   }
  392.  
  393.   elementsPerGroup = luminanceSize + alphaSize + rgbSize;
  394.   elementSize = sizeof(GLubyte);
  395.   groupSize = elementsPerGroup * elementSize;
  396.   rowSize = width * groupSize;
  397.  
  398.   if ((texImage = (GLubyte *) malloc(height * rowSize)) == NULL) {
  399.     fprintf(stderr, "texture malloc failed\n");
  400.     return;
  401.   }
  402.   for (i = 0; i < height; ++i) {
  403.     p = texImage + i * rowSize;
  404.     for (j = 0; j < width; ++j) {
  405.       if (luminanceSize > 0) {
  406.         /** 
  407.          ** +-----+-----+
  408.      ** |     |     |
  409.      ** |  W  | LG  |
  410.      ** |     |     |
  411.      ** +-----+-----+
  412.      ** |     |     |
  413.      ** | DG  |  B  |
  414.      ** |     |     |
  415.      ** +-----+-----+
  416.      **/
  417.         if (i > height / 2) {
  418.           if (j < width / 2) {
  419.             p[0] = 0xff;
  420.           } else {
  421.             p[0] = 0xaa;
  422.           }
  423.         } else {
  424.           if (j < width / 2) {
  425.             p[0] = 0x55;
  426.           } else {
  427.             p[0] = 0x00;
  428.           }
  429.         }
  430.         p += elementSize;
  431.       }
  432.       if (rgbSize > 0) {
  433.         /**
  434.          ** +-----+-----+
  435.      ** |     |     |
  436.      ** |  R  |  G  |
  437.          ** |     |     |
  438.      ** +-----+-----+
  439.      ** |     |     |
  440.          ** |  Y  |  B  |
  441.      ** |     |     |
  442.      ** +-----+-----+
  443.      **/
  444.         if (i > height / 2) {
  445.           if (j < width / 2) {
  446.             p[0] = 0xff;
  447.             p[1] = 0x00;
  448.             p[2] = 0x00;
  449.           } else {
  450.             p[0] = 0x00;
  451.             p[1] = 0xff;
  452.             p[2] = 0x00;
  453.           }
  454.         } else {
  455.           if (j < width / 2) {
  456.             p[0] = 0xff;
  457.             p[1] = 0xff;
  458.             p[2] = 0x00;
  459.           } else {
  460.             p[0] = 0x00;
  461.             p[1] = 0x00;
  462.             p[2] = 0xff;
  463.           }
  464.         }
  465.         p += 3 * elementSize;
  466.       }
  467.       if (alphaSize > 0) {
  468.         /**
  469.          ** +-----------+
  470.      ** |     W     |
  471.      ** |  +-----+  |
  472.          ** |  |     |  |
  473.      ** |  |  B  |  |
  474.      ** |  |     |  |
  475.          ** |  +-----+  |
  476.      ** |           |
  477.      ** +-----------+
  478.      **/
  479.         int i2 = i - height / 2;
  480.         int j2 = j - width / 2;
  481.         int h8 = height / 8;
  482.         int w8 = width / 8;
  483.         if (-h8 <= i2 && i2 <= h8 && -w8 <= j2 && j2 <= w8) {
  484.           p[0] = 0x00;
  485.         } else if (-2 * h8 <= i2 && i2 <= 2 * h8 && -2 * w8 <= j2 && j2 <= 2 * w8) {
  486.           p[0] = 0x55;
  487.         } else if (-3 * h8 <= i2 && i2 <= 3 * h8 && -3 * w8 <= j2 && j2 <= 3 * w8) {
  488.           p[0] = 0xaa;
  489.         } else {
  490.           p[0] = 0xff;
  491.         }
  492.         p += elementSize;
  493.       }
  494.     }
  495.   }
  496.  
  497.   glTexImage2D(GL_TEXTURE_2D, 0,
  498.     format->internalFormat, width, height, 0,
  499.     textureFormat, GL_UNSIGNED_BYTE, texImage);
  500.  
  501.   free(texImage);
  502. }
  503.  
  504. static void
  505. drawCheck(int w, int h, GLfloat lightCheck[4], GLfloat darkCheck[4])
  506. {
  507.   float dw = 2.0 / w;
  508.   float dh = 2.0 / h;
  509.   int i, j;
  510.  
  511.   for (i = 0; i < w; ++i) {
  512.     GLfloat x0 = -1.0 + i * dw;
  513.     GLfloat x1 = x0 + dw;
  514.  
  515.     glBegin(GL_QUAD_STRIP);
  516.     for (j = 0; j <= h; ++j) {
  517.       GLfloat y = -1.0 + j * dh;
  518.  
  519.       if ((i ^ j) & 1) {
  520.         glColor4fv(lightCheck);
  521.       } else {
  522.         glColor4fv(darkCheck);
  523.       }
  524.  
  525.       glVertex2f(x0, y);
  526.       glVertex2f(x1, y);
  527.     }
  528.     glEnd();
  529.   }
  530. }
  531.  
  532. static void
  533. drawSample(int x, int y, int w, int h,
  534.   struct formatInfo *format, struct envModeInfo *envMode)
  535. {
  536.   glViewport(x, y, w, h);
  537.   glScissor(x, y, w, h);
  538.  
  539.   glClearColor(0.1, 0.1, 0.1, 1.0);
  540.   glClear(GL_COLOR_BUFFER_BIT);
  541.  
  542.   begin2D(w, h);
  543.   drawString(format->name, 10, h - 15, labelInfoColor);
  544.   drawString(envMode->name, 10, 5, labelInfoColor);
  545.   end2D();
  546.  
  547.   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, envMode->mode);
  548.   glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, envColors[envColor]);
  549.  
  550.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  551.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  552.  
  553.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  554.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  555.  
  556.   loadTexture(textureWidth, textureHeight, format);
  557.  
  558.   if (drawBackground) {
  559.     drawCheck(15, 15, lightCheck, darkCheck);
  560.   }
  561.   if (drawBlended) {
  562.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  563.     glEnable(GL_BLEND);
  564.   }
  565.   if (drawSmooth) {
  566.     glShadeModel(GL_SMOOTH);
  567.   }
  568.   if (drawTextured) {
  569.     glEnable(GL_TEXTURE_2D);
  570.   }
  571.   glBegin(GL_QUADS);
  572.   glColor4f(1.0, 0.0, 0.0, 1.0);
  573.   glTexCoord2f(0.0, 0.0);
  574.   glVertex2f(-0.8, -0.8);
  575.   glColor4f(0.0, 1.0, 0.0, 1.0);
  576.   glTexCoord2f(1.0, 0.0);
  577.   glVertex2f(0.8, -0.8);
  578.   glColor4f(0.0, 0.0, 1.0, 1.0);
  579.   glTexCoord2f(1.0, 1.0);
  580.   glVertex2f(0.8, 0.8);
  581.   glColor4f(1.0, 1.0, 1.0, 1.0);
  582.   glTexCoord2f(0.0, 1.0);
  583.   glVertex2f(-0.8, 0.8);
  584.   glEnd();
  585.  
  586.   glDisable(GL_BLEND);
  587.   glShadeModel(GL_FLAT);
  588.   glDisable(GL_TEXTURE_2D);
  589.  
  590.   if (displayLevelInfo) {
  591.     GLint width, height, border, components;
  592. #if GL_EXT_texture
  593.     GLint redSize, greenSize, blueSize, alphaSize;
  594.     GLint luminanceSize, intensitySize;
  595. #endif
  596.     char buf[255];
  597.  
  598.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  599.       GL_TEXTURE_WIDTH, &width);
  600.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  601.       GL_TEXTURE_HEIGHT, &height);
  602.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  603.       GL_TEXTURE_BORDER, &border);
  604.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  605.       GL_TEXTURE_COMPONENTS, &components);
  606. #if GL_EXT_texture
  607.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  608.       GL_TEXTURE_RED_SIZE_EXT, &redSize);
  609.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  610.       GL_TEXTURE_GREEN_SIZE_EXT, &greenSize);
  611.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  612.       GL_TEXTURE_BLUE_SIZE_EXT, &blueSize);
  613.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  614.       GL_TEXTURE_ALPHA_SIZE_EXT, &alphaSize);
  615.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  616.       GL_TEXTURE_LUMINANCE_SIZE_EXT, &luminanceSize);
  617.     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
  618.       GL_TEXTURE_INTENSITY_SIZE_EXT, &intensitySize);
  619. #endif
  620.  
  621.     begin2D(w, h);
  622.     sprintf(buf, "dimensions: %d x %d", width, height);
  623.     drawStringOutline(buf, 15, h / 2 + 20, labelLevelColor0, labelLevelColor1);
  624.  
  625.     sprintf(buf, "border: %d", border);
  626.     drawStringOutline(buf, 15, h / 2 + 10, labelLevelColor0, labelLevelColor1);
  627.  
  628.     sprintf(buf, "components: 0x%04X", components);
  629.     drawStringOutline(buf, 15, h / 2, labelLevelColor0, labelLevelColor1);
  630.  
  631.     sprintf(buf, "sizes:");
  632.     drawStringOutline(buf, 15, h / 2 - 10, labelLevelColor0, labelLevelColor1);
  633.  
  634. #if GL_EXT_texture
  635.     sprintf(buf, "  %d/%d/%d/%d/%d/%d",
  636.       redSize, greenSize, blueSize, alphaSize,
  637.       luminanceSize, intensitySize);
  638.     drawStringOutline(buf, 15, h / 2 - 20, labelLevelColor0, labelLevelColor1);
  639. #endif
  640.     end2D();
  641.   }
  642. }
  643.  
  644. static void
  645. display(void)
  646. {
  647.   int numX = NUM_ENV_MODES, numY = NUM_BASE_FORMATS;
  648.   float xBase = (float) winWidth * 0.01;
  649.   float xOffset = (winWidth - xBase) / numX;
  650.   float xSize = max(xOffset - xBase, 1);
  651.   float yBase = (float) winHeight * 0.01;
  652.   float yOffset = (winHeight - yBase) / numY;
  653.   float ySize = max(yOffset - yBase, 1);
  654.   float x, y;
  655.   int i, j;
  656.  
  657.   glViewport(0, 0, winWidth, winHeight);
  658.   glDisable(GL_SCISSOR_TEST);
  659.   glClearColor(0.0, 0.0, 0.0, 0.0);
  660.   glClear(GL_COLOR_BUFFER_BIT);
  661.   glEnable(GL_SCISSOR_TEST);
  662.  
  663.   x = xBase;
  664.   y = (winHeight - 1) - yOffset;
  665.   for (i = 0; i < NUM_BASE_FORMATS; ++i) {
  666.     struct formatInfo *format;
  667.  
  668.     if (i == baseFormat) {
  669.       labelInfoColor = labelColor1;
  670.     } else {
  671.       labelInfoColor = labelColor0;
  672.     }
  673.  
  674.     format = &baseFormats[i].format[baseFormats[i].current];
  675.     for (j = 0; j < NUM_ENV_MODES; ++j) {
  676.       struct envModeInfo *envMode;
  677.  
  678.       envMode = &envModes[j];
  679.       drawSample(x, y, xSize, ySize, format, envMode);
  680.       x += xOffset;
  681.     }
  682.     x = xBase;
  683.     y -= yOffset;
  684.   }
  685.  
  686.   if (doubleBuffered) {
  687.     glutSwapBuffers();
  688.   } else {
  689.     glFlush();
  690.   }
  691.  
  692.   checkErrors();
  693. }
  694.  
  695. static void
  696. usage(char *name)
  697. {
  698.   fprintf(stderr, "\n");
  699.   fprintf(stderr, "usage: %s [ options ]\n", name);
  700.   fprintf(stderr, "\n");
  701.   fprintf(stderr, "    Tests texture environments and internal formats\n");
  702.   fprintf(stderr, "\n");
  703.   fprintf(stderr, "  Options:\n");
  704.   fprintf(stderr, "    -sb  single buffered\n");
  705.   fprintf(stderr, "    -db  double buffered\n");
  706.   fprintf(stderr, "\n");
  707. }
  708.  
  709. int
  710. main(int argc, char *argv[])
  711. {
  712.   int i;
  713.  
  714.   glutInit(&argc, argv);
  715.   for (i = 1; i < argc; ++i) {
  716.     if (!strcmp("-sb", argv[i])) {
  717.       doubleBuffered = GL_FALSE;
  718.     } else if (!strcmp("-db", argv[i])) {
  719.       doubleBuffered = GL_TRUE;
  720.     } else {
  721.       usage(argv[0]);
  722.       exit(1);
  723.     }
  724.   }
  725.  
  726. #if !GL_EXT_texture
  727.   printf("WARNING: client-side OpenGL implementation lacks\n");
  728.   printf("         the GL_EXT_texture extension!\n");
  729.   printf("         Skipping GL_EXT_texture functionality...\n");
  730. #endif
  731.  
  732.   if (doubleBuffered) {
  733.     glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
  734.   } else {
  735.     glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
  736.   }
  737.  
  738.   glutInitWindowSize(winWidth, winHeight);
  739.   glutCreateWindow("Texture Environment Test");
  740.  
  741.   if (!glutExtensionSupported("GL_EXT_texture")) {
  742.     fprintf(stderr, "missing extension: GL_EXT_texture\n");
  743.     exit(1);
  744.   }
  745.   initialize();
  746.  
  747.   glutDisplayFunc(display);
  748.   glutReshapeFunc(reshape);
  749.   glutKeyboardFunc(keyboard);
  750.   glutSpecialFunc(special);
  751.   glutMainLoop();
  752.   return 0;             /* ANSI C requires main to return int. */
  753. }
  754.